/**
 * 名字标签挂件：CGCR 2018 的 LOGO 底部横幅
 * 
 * 注意: 因为是挂件, 所以没有 sendStatus 这个方法.
 * 该挂件的 Pendant 实例需要调用 sendStatus 方法, 因此需要上层设置 sendStatus 方法
 */

/**
 * public 创建 Pendant 挂件方法
 */
function createPendant(context) {
  let t = new CGCR2018Logo(context);
  let p = new context.Pendant({
		require : ['zrender'],
		init : (libs, options) => t.init(libs, options),
		destroy : () => t.destroy(),
  });
  t.finished = () => p.finished();
  return p;
};

let zrender = null;

/**
 * 上层的 Scene 会注入 finished 方法.
 */
class CGCR2018Logo {

  /** @type {number} */
  intervalHandler = null;

  status = 0;

  sprites = {
    pImgLogo : null,

    /** 中间那个分割线 */
    pSplit : null,

    /** 右半边的切片 */
    pClip : null,

    /** 左边出现的文本. 第一行是英文. ZImage 实例 */
    pText1 : null,

    /** 第二行是中文. ZImage 实例 */
    pText2 : null,

    /** 第三行是时间地点. ZImage 实例 */
    pText3 : null,
  };

  layout = {
    /** LOGO 的高 （动画中的长度）*/
    vLogoHeight : 50,
    /** LOGO 的宽 （动画中的长度）*/
    vLogoWidth : 0,

    /** 中间那个分割线的位置，X 轴. 动画过程中是常量 */
    vSplitX : 0,

    /** pText1 横坐标. 变化 */
    vText1X : 0,
    /** pText2 纵坐标. 变化 */
    vText2Y : 0,
    /** pText2 横坐标. 静态 */
    vText2X : 0,
    /** pText3 纵坐标. 变化 */
    vText3Y : 0,
    /** pText3 横坐标. 静态 */
    vText3X : 0,

    centerY : 0,
    logoY : 0,
    /** 文字停止时, y 位置 */
    textY : 0,

    canvasWidth : 0,
    canvasHeight : 0,
  };

  context = null;
  zr = null;

  props = {
    el : 'main',
  };
  
  constructor(context) {
    this.context = context;
  };

  init (libs, args) {
    if (args) {
      Object.assign(this.props, args);
    }

    zrender = libs.zrender;
    let zr = this.zr = zrender.init(document.getElementById(this.props.el));

    let w = this.layout.canvasWidth = zr.getWidth();
    let h = this.layout.canvasHeight = zr.getHeight();
    this.layout.centerY = h / 2;

    // CGCR LOGO.png
    this.layout.vLogoWidth = this.layout.vLogoHeight / 129 * 539; // 改变数值在这里
    this.layout.logoY = this.layout.centerY - this.layout.vLogoHeight / 2; // 8

    zr.add(this.sprites.pImgLogo = createLogo(this.context.assetPath('asset/CGCR2018_LOGO.png'),
      this.layout.vLogoWidth, this.layout.logoY, w));

    // 分割线
    this.layout.vSplitX = w / 2 - 300;
    zr.add(this.sprites.pSplit = new zrender.Rect({
      shape : {
        width : 4,
        height : 0
      },
      style : {
        fill : '#FFFFFFAA'
      },
      position : [this.layout.vSplitX, h / 2],
      z: 0
    }));

    // 文本 (ZImage)
    this.layout.textY = this.layout.centerY - this.layout.vLogoHeight / 2; // 12
    zr.add(this.sprites.pText1 = new zrender.Image({
      style : {
        image: this.context.assetPath('asset/CGCR2018_英文.png'),
        x: 0,
        y: 0,
        height: this.layout.vLogoHeight,
        opacity: 0
      },
      position : [0, this.layout.textY]
    }));

    this.layout.vText2X = this.layout.vSplitX + 100;
    this.layout.vText2Y = this.layout.textY;
    zr.add(this.sprites.pText2 = new zrender.Image({
      style : {
        image: this.context.assetPath('asset/CGCR2018_中文.png'),
        x: 0,
        y: 0,
        height: this.layout.vLogoHeight,
        opacity: 0
      },
      position : [0, this.layout.vText2Y]
    }));

    this.layout.vText3X = this.layout.vSplitX + 100;
    this.layout.vText3Y = this.layout.textY;
    zr.add(this.sprites.pText3 = new zrender.Image({
      style : {
        image: this.context.assetPath('asset/CGCR2018_时间地点.png'),
        x: 0,
        y: 0,
        height: this.layout.vLogoHeight,
        opacity: 0
      },
      position : [0, this.layout.vText3Y]
    }));

    this.intervalHandler = setInterval(() => this.tick(), 1000 / 60); // 60fps
  };

  tick () {
    switch (this.status) {
    case 0: this.animateS0(); break;
    // 1 在动画中
    case 2: this.status = 3; setTimeout(() => this.status = 100, 4500); break;

    case 100: this.animateS100(); break;
    case 101: this.animateS101(); break; // 101: 100 部分在动画中
    case 102: this.status = 103; setTimeout(() => this.status = 200, 4500); break;

    case 200: this.animateS200(); break;
    // 201 在动画中
    case 202: this.status = 203; setTimeout(() => this.status = 300, 4500); break;

    case 300: this.animateS300(); break;
    // 301 在动画中
    case 302: this.status = 203; setTimeout(() => this.status = 400, 4500); break;

    case 400: this.animateS400(); break;
    // 401 在动画中, 退出的动画
    case 402: this.status = 403; setTimeout(() => this.status = 500, 1500); break;

    case 500: this.finished(); break; // 该部分动画结束
    }
  };

  destroy () {
    clearInterval(this.intervalHandler);
  };

  /* ***********
   * 动画部分区 *
   *********** */

  animateS0() {
    const {vLogoWidth, logoY, canvasWidth} = this.layout;
    const {pImgLogo} = this.sprites;

    let x = canvasWidth / 2 - vLogoWidth / 2;

    // Logo 淡入出现
    pImgLogo.attr({
      position: [x, logoY],
      style: { opacity: 0 }
    });

    pImgLogo.animate('style', false)
      .when(500, {opacity : 1})
      .done(() => this.status = 2)
      .start();

    this.status = 1;
  };

  animateS100 () {
    const {textY, vSplitX, vLogoWidth, canvasHeight} = this.layout;
    const {pText1, pImgLogo, pSplit} = this.sprites;

    this.status = 101;
    this.layout.vText1X = -400;
    pText1.attr({
      position:[this.layout.vText1X, textY],
      style:{opacity: 0}
    });

    pImgLogo.animate('position', false)
      .when(1000, [vSplitX - vLogoWidth - 100])
      .start('cubicInOut');

    pSplit.animate('position', false)
      .delay(500)
      .when(500, [vSplitX, canvasHeight / 2 - 25])
      .start('cubicInOut');

    pSplit.animate('shape', false)
      .delay(500)
      .when(500, {
        height : 50
      })
      .start('cubicInOut');

    pText1.animate('style', false)
      .delay(500)
      .when(500, {opacity:1})
      .start('cubicInOut');
  };

  animateS101 () {
    const {vSplitX, textY, canvasWidth, canvasHeight} = this.layout;
    const {pText1} = this.sprites;

    let dest = vSplitX + 100;
    let delta = dest - this.layout.vText1X;
    if (delta < 0.1) {
      this.layout.vText1X = dest;
    } else {
      let dd = delta / 20;
      if (dd < 0.1) {
        dd = 0.1;
      } else if (dd > 10) {
        dd = 10;
      }
      this.layout.vText1X += dd;
    }

    if (this.layout.vText1X >= dest) {
      this.layout.vText1X = dest;
      this.status = 102;
    }

    pText1.attr({position:[this.layout.vText1X, textY]});
    // this.pText1.attr({position:[0, 0]});

    //this.zr.remove(this.pClip);
    this.sprites.pClip = new zrender.Rect({
      shape : {
        x : vSplitX + 4 - this.layout.vText1X, // 4 是分割线的宽度
        y : -textY,
        width : canvasWidth,
        height : canvasHeight
      },
      position : [0, 0],
      z: -1 // 测试使用
    });
    pText1.setClipPath(this.sprites.pClip);
  };

  animateS200 () {
    this.status = 201;
    const {vText1X, vText2X, vText2Y, textY, canvasHeight} = this.layout;
    const {pText1, pText2} = this.sprites;

    pText2.attr({
      position:[vText2X, vText2Y + canvasHeight],
      style:{opacity:1}
    });
    pText1.removeClipPath();

    pText1.animate('position', false)
      .when(1000, [vText1X, textY - canvasHeight])
      .done(() => this.status = 202)
      .start('cubicInOut');

    pText2.animate('position', false)
      .when(1000, [vText2X, vText2Y])
      .start('cubicInOut');
  };

  animateS300 () {
    this.status = 301;
    const {vText2X, vText2Y, vText3X, vText3Y, canvasHeight} = this.layout;
    const {pText2, pText3} = this.sprites;

    pText3.attr({
      position:[vText3X, vText3Y + canvasHeight],
      style:{opacity:1}
    });

    pText2.animate('position', false)
      .when(1000, [vText2X, vText2Y - canvasHeight])
      .done(() => this.status = 302)
      .start('cubicInOut');

    pText3.animate('position', false)
      .when(1000, [vText3X, vText3Y])
      .start('cubicInOut');
  };

  animateS400 () {
    this.status = 401;
    const {vSplitX, vText3X, vText3Y, canvasHeight} = this.layout;
    const {pImgLogo, pSplit, pText3} = this.sprites;

    pText3.animate('position', false)
      .when(1000, [vText3X, vText3Y - canvasHeight])
      .done(() => this.status = 402)
      .start('cubicInOut');

    pImgLogo.animate('style', false)
      .delay(500)
      .when(500, {opacity : 0})
      .start();

    pSplit.animate('position', false)
      .delay(200)
      .when(500, [vSplitX, canvasHeight / 2])
      .start('cubicInOut');

    pSplit.animate('shape', false)
      .delay(200)
      .when(500, {
        height : 0
      })
      .start('cubicInOut');
  };
};

/**
 * @param {string} path 
 * @param {number} vLogoWidth 
 * @param {number} logoY 
 */
function createLogo(path, vLogoWidth, logoY, canvasWidth) {
  return new zrender.Image({
    style: {
      image: path,
      x: 0,
      y: 0,
      width: vLogoWidth,
      height: 50,
      opacity: 0,
      shadowBlur: 5,
      shadowColor: '#FFFFFF88'
    },
    position: [canvasWidth / 2 - vLogoWidth / 2, logoY],
    z: 100
  });
}

  // 对外开放哪些方法
export default createPendant;
